﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;

namespace FireCounter;

public static class TextBoxPlaceholder
{
    public static readonly DependencyProperty PlaceholderProperty = DependencyProperty.RegisterAttached(
        "Placeholder", typeof(string), typeof(TextBoxPlaceholder),
        new PropertyMetadata("请在此处输入...", OnPlaceholderChanged));

    private static readonly Dictionary<TextBox, VisualBrush> _textBoxBrushes = new();

    public static string GetPlaceholder(DependencyObject obj)
    {
        return (string)obj.GetValue(PlaceholderProperty);
    }

    public static void OnPlaceholderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if ((d is TextBox tb) && (!_textBoxBrushes.ContainsKey(tb)))
        {
            var placeholderTextBlock = new TextBlock();
            var binding = new Binding
            {
                Source = tb,
                Path = new PropertyPath("(0)", PlaceholderProperty)
            };
            placeholderTextBlock.SetBinding(TextBlock.TextProperty, binding);
            placeholderTextBlock.FontStyle = FontStyles.Italic;
            placeholderTextBlock.Foreground = new SolidColorBrush(Colors.Gray);

            var placeholderVisualBrush = new VisualBrush
            {
                AlignmentX = AlignmentX.Left,
                Stretch = Stretch.None,
                Visual = placeholderTextBlock
            };

            tb.Background = placeholderVisualBrush;

            tb.TextChanged += PlaceholderTextBox_TextChanged;
            tb.Unloaded += PlaceholderTextBox_Unloaded;

            _textBoxBrushes.Add(tb, placeholderVisualBrush);
        }
    }

    public static void SetPlaceholder(DependencyObject obj, string value)
    {
        obj.SetValue(PlaceholderProperty, value);
    }

    private static void PlaceholderTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        if ((sender is TextBox tb) && _textBoxBrushes.ContainsKey(tb))
        {
            var placeholderVisualBrush = _textBoxBrushes[tb];
            tb.Background = String.IsNullOrEmpty(tb.Text) ? placeholderVisualBrush : null;
        }
    }

    private static void PlaceholderTextBox_Unloaded(object sender, RoutedEventArgs e)
    {
        if ((sender is TextBox tb) && _textBoxBrushes.ContainsKey(tb))
        {
            _textBoxBrushes.Remove(tb);

            tb.TextChanged -= PlaceholderTextBox_TextChanged;
            tb.Unloaded -= PlaceholderTextBox_Unloaded;
        }
    }
}
